# +----------------------------------------------------------------------
# | ChatWork智能聊天办公系统
# +----------------------------------------------------------------------
# | 软件声明: 本系统并非自由软件,未经授权任何形式的商业使用均属非法。
# | 版权保护: 任何企业和个人不允许对程序代码以任何形式任何目的复制/分发。
# | 授权要求: 如有商业使用需求,请务必先与版权所有者取得联系并获得正式授权。
# +----------------------------------------------------------------------
# | Author: ChatWork Team <2474369941@qq.com>
# +----------------------------------------------------------------------
from tortoise.queryset import Q
from exception import AppException
from common.utils.urls import UrlUtil
from common.enums.pay import PayEnum
from common.models.users import UserModel
from common.models.public import RefundRecordModel
from common.service.refund_logic import RefundLogic
from apps.admin.schemas.finance import refund_schema as schema


class RefundService:

    @classmethod
    async def lists(cls, params: schema.RefundSearchIn):
        where = RefundRecordModel.build_search({
            "=": ["scene", "order_sn", "refund_sn"],
            "datetime": ["start_time|end_time@create_time"]
        }, params.__dict__)

        if params.type and params.type != "all":
            status = {"ing": PayEnum.REFUND_ING, "ok": PayEnum.REFUND_OK, "fail": PayEnum.REFUND_FAIL}
            where.append(Q(refund_status=status.get(params.type, 0)))

        if params.user:
            user = await (UserModel
                          .filter(Q(sn=params.user) | Q(mobile=params.user) | Q(nickname=params.user))
                          .filter(is_delete=0)
                          .limit(300)
                          .values("id"))

            user_ids = [item["id"] for item in user if item["id"]] or [0]
            where.append(Q(user_id__in=list(set(user_ids))))

        _model = RefundRecordModel.filter(*where).order_by("-id")
        _pager = await RefundRecordModel.paginate(
            model=_model,
            page_no=params.page_no,
            page_size=params.page_size
        )

        user_ids = [item["user_id"] for item in _pager.lists if item["user_id"]]
        users: dict = await UserModel.queryUserDictsById(user_ids)

        _lists = []
        for item in _pager.lists:
            user = users.get(item["user_id"]) or {}
            _lists.append(schema.RefundListVo(
                id=item["id"],
                refund_sn=item["refund_sn"],
                order_sn=item["order_sn"],
                total_amount=item["total_amount"],
                refund_amount=item["refund_amount"],
                refund_status=item["refund_status"],
                create_time=item["create_time"],
                user={
                    "sn": user.get("sn", ""),
                    "avatar": await UrlUtil.to_absolute_url(user.get("avatar", "")),
                    "nickname": user.get("nickname", ""),
                    "mobile": user.get("mobile", "")
                }
            ))

        whole = await RefundRecordModel.all().count()
        fail = await RefundRecordModel.filter(refund_status=PayEnum.REFUND_FAIL).all().count()
        ing = await RefundRecordModel.filter(refund_status=PayEnum.REFUND_ING).all().count()
        ok = await RefundRecordModel.filter(refund_status=PayEnum.REFUND_OK).all().count()

        _pager.lists = _lists
        _pager.extend = {
            "all": whole,
            "fail": fail,
            "ing": ing,
            "ok": ok
        }

        return _pager

    @classmethod
    async def again_refund(cls, record_id: int, admin_id: int):
        record = await RefundRecordModel.filter(id=record_id).get()
        if record.refund_status == PayEnum.REFUND_OK:
            raise AppException("该订单已退款了")

        try:
            await RefundLogic.refund(
                scene=record.refund_type,
                order_id=record.order_id,
                refund_amount=record.refund_amount,
                admin_id=admin_id
            )
        except Exception as e:
            raise AppException(str(e))
